#ifndef LEAKY_RELU_HPP
#define LEAKY_RELU_HPP

#include "Neuron.hpp"  // 依赖Neuron基类头文件
#include <random>
#include <stdexcept>

/**
 * LeakyReLU神经元类（继承自Neuron基类）
 * 激活函数：LeakyReLU(x) = max(slope * x, x)，slope为负斜率（默认0.01）
 * 导数：x>0时为1，x≤0时为slope
 */
class LeakyNeuron : public Neuron {
private:
    double slope;  // LeakyReLU的负斜率参数（核心区别于普通ReLU）

protected:
    /**
     * LeakyReLU激活函数实现
     * @param x 激活前的加权和（pre_act）
     * @return 激活后的值
     */
    double actFunc(double x) const override {
        return std::max(slope * x, x);
    }

    /**
     * LeakyReLU导数实现（解决普通ReLU的"死亡神经元"问题）
     * @param x 激活前的加权和（pre_act）
     * @return 导数结果
     */
    double actFuncDeriv(double x) const override {
        return x > 0.0 ? 1.0 : slope;
    }

public:
    /**
     * 构造函数：初始化权重、偏置和负斜率
     * @param inputSize 输入维度（前一层神经元数量）
     * @param slope 负斜率（默认0.01，建议范围0.01~0.1）
     */
    LeakyNeuron(size_t inputSize, double slope = 0.01) 
        : Neuron(inputSize), slope(slope) {
        // He初始化（适配LeakyReLU的权重初始化策略）
        std::random_device rd;
        std::mt19937 gen(rd());
        std::normal_distribution<double> dist(0.0, std::sqrt(2.0 / inputSize));
        
        // 初始化权重
        for (auto& w : weights) {
            w = dist(gen);
        }
        // 初始化偏置（同权重分布）
        bias = dist(gen);
    }

    /**
     * 计算神经元输出（重写基类接口）
     * @param inputs 前一层的输出向量
     * @return 激活后的输出值
     */
    double count(const std::vector<double>& inputs) override {
        if (inputs.size() != weights.size()) {
            throw std::invalid_argument("LeakyNeuron: 输入维度与权重维度不匹配");
        }
        // 计算加权和 + 偏置（激活前值）
        pre_act = bias;
        for (size_t i = 0; i < inputs.size(); ++i) {
            pre_act += inputs[i] * weights[i];
        }
        // 应用LeakyReLU激活函数（激活后值）
        post_act = actFunc(pre_act);
        return post_act;
    }

    /**
     * 获取当前神经元的负斜率（用于模型保存/加载）
     * @return 负斜率值
     */
    double getSlope() const {
        return slope;
    }

    /**
     * 设置神经元的负斜率（可选接口）
     * @param newSlope 新的负斜率值
     */
    void setSlope(double newSlope) {
        if (newSlope < 0 || newSlope >= 1) {
            throw std::invalid_argument("LeakyNeuron: 负斜率需在[0,1)范围内");
        }
        slope = newSlope;
    }

    // 虚析构函数（确保子类析构正常）
    virtual ~LeakyNeuron() = default;
};

#endif  // LEAKY_RELU_HPP